package starter.context;

import java.sql.Connection;
import java.util.Map;

import com.alibaba.druid.pool.DruidDataSource;
import com.bowlong.sql.SqlEx;
import com.bowlong.util.Log;
import com.bowlong.util.MapEx;

import static com.bowlong.util.Log.e2s;

@SuppressWarnings("unchecked")
public class MySqlContext {
	final Map<String, Object> map;

	public MySqlContext(String key) {
		map = MapEx.getMap(App.ctx(), key);

		this.driverClassName = MapEx.getString(map, "driverClassName");
		this.url = MapEx.getString(map, "url");
		this.username = MapEx.getString(map, "username");
		this.password = MapEx.getString(map, "password");
		this.maxActive = MapEx.getInt(map, "maxActive");
		this.maxIdle = MapEx.getInt(map, "maxIdle");
		this.maxWait = MapEx.getInt(map, "maxWait");
		this.removeAbandoned = MapEx.getBoolean(map, "removeAbandoned");
		this.removeAbandonedTimeout = MapEx.getInt(map,
				"removeAbandonedTimeout");
		this.validationQuery = MapEx.getString(map, "validationQuery");
		this.validationQueryTimeout = MapEx.getInt(map,
				"validationQueryTimeout");
		this.testOnBorrow = MapEx.getBoolean(map, "testOnBorrow");
		this.testOnReturn = MapEx.getBoolean(map, "testOnReturn");
		this.testWhileIdle = MapEx.getBoolean(map, "testWhileIdle");
		this.dataSource = dataSource();
	}

	public final DruidDataSource dataSource;

	public final String driverClassName;
	public final String url;
	public final String username;
	public final String password;
	public final int maxActive;
	public final int maxIdle;
	public final int maxWait;
	public final boolean removeAbandoned;
	public final int removeAbandonedTimeout;
	public final String validationQuery;
	public final int validationQueryTimeout;
	public final boolean testWhileIdle;
	public final boolean testOnBorrow;
	public final boolean testOnReturn;

	private final DruidDataSource dataSource() {
		DruidDataSource ds = new DruidDataSource();
		ds.setDriverClassName(driverClassName);
		ds.setUrl(url);
		ds.setUsername(username);
		ds.setPassword(password);
		ds.setMaxActive(maxActive);
		ds.setMinIdle(maxIdle);
		ds.setInitialSize(maxIdle);
		ds.setMaxWait(maxWait);

		ds.setRemoveAbandoned(removeAbandoned);
		ds.setRemoveAbandonedTimeout(removeAbandonedTimeout);
		ds.setTimeBetweenEvictionRunsMillis(60000);
		ds.setMinEvictableIdleTimeMillis(300000);
		ds.setPoolPreparedStatements(false);
		// ds.setMaxPoolPreparedStatementPerConnectionSize(64);
		// ds.setLogAbandoned(true);
		ds.setValidationQuery(validationQuery);
		ds.setTestWhileIdle(testWhileIdle);
		ds.setTestOnBorrow(testOnBorrow);
		ds.setTestOnReturn(testOnReturn);
		ds.setValidationQueryTimeout(validationQueryTimeout);

		return ds;
	}

	public void testConnection() {
		int num = 128;
		testConnection(num);
	}

	public void testConnection(int num) {
		DruidDataSource ds = dataSource();
		for (int i = 0; i < num; i++) {
			try {
				Connection conn = ds.getConnection();
				SqlEx.execute(conn, validationQuery);
				conn.close();
			} catch (Exception e) {
				Log.error(e2s(e));
			}
		}
	}
}
